﻿--[[
Name: BrownieHelper
Developed by: Sonora (The Dragon Flight)
Website: http://sonora.kirintor.googlepages.com/contents
SVN: http://code.google.com/p/browniehelper/source/browse
License: GNU General Public License v3
]]

--From wowwiki 3/8/08, maps returns to itemEquipLoc from GetItemInfo to 1-4 inventory slotids
local inventorySlotTranslations = {
    [""] = {},
    ["INVTYPE_AMMO"] = {0}, 
    ["INVTYPE_HEAD"] = {1},
    ["INVTYPE_NECK"] = {2},
    ["INVTYPE_SHOULDER"] = {3},
    ["INVTYPE_BODY"] = {4},
    ["INVTYPE_CHEST"] = {5},
    ["INVTYPE_ROBE"] = {5},
    ["INVTYPE_WAIST"] = {6},
    ["INVTYPE_LEGS"] = {7},
    ["INVTYPE_FEET"] = {8},
    ["INVTYPE_WRIST"] = {9},
    ["INVTYPE_HAND"] = {10},
    ["INVTYPE_FINGER"] = {11,12},
    ["INVTYPE_TRINKET"] = {13,14},
    ["INVTYPE_CLOAK"] = {15},
    ["INVTYPE_WEAPON"] = {16,17},
    ["INVTYPE_SHIELD"] = {17},
    ["INVTYPE_2HWEAPON"] = {16},
    ["INVTYPE_WEAPONMAINHAND"] = {16},
    ["INVTYPE_WEAPONOFFHAND"] = {17},
    ["INVTYPE_HOLDABLE"] = {17},
    ["INVTYPE_RANGED"] = {18},
    ["INVTYPE_THROWN"] = {18},
    ["INVTYPE_RANGEDRIGHT"] = {18},
    ["INVTYPE_RELIC"] = {18},
    ["INVTYPE_TABARD"] = {19},
    ["INVTYPE_BAG"] = {20,21,22,23},
    ["INVTYPE_QUIVER"] = {20,21,22,23},
}

function AuctionWizardFrame:Initialize(app)

    --Make sure we always have these
    self.itemInfo = {}
    self.bidSetup = {}
    self.bids = {}

    --Save the app
    self.app = app
    
    --Track whether or not whisper tracking is on
    self.whisperTracking = false
    
    --Register for incomming chat commands via whisper
    self.app:registerEvent("CHAT_MSG_WHISPER", function(message, author) self:recieveWhisper(author, message) end)
    
    --Setup the table
    AuctionWizardBidTable:setFields({"Player","Character","Points","Bid","Roll"})
    AuctionWizardBidTable.multiselect=false,
    AuctionWizardBidTable:registerSelectionCallback(
        function(row, selected)
            if self.app:getMode()>=BROWNIEHELPER_MASTERLOOTER then
                self:bidSelected(row, selected)
            end
        end)
    AuctionWizardBidTable:registerRowEnterCallback(function(row) self:rowEnter(row) end)
    AuctionWizardBidTable:registerRowLeaveCallback(function(row) self:rowLeave(row) end)
    AuctionWizardBidTable:registerDoubleClickCallback(function (row) self:inspectPlayer(row) end)
    
    --register for events
    self.app:registerEvent("BrownieHelper_AuctionStateChanged",
        function(state, itemInfo, bidSetup)
            if state==BROWNIEHELPER_PREAUCTION then self:initializeAuction(itemInfo, bidSetup) end
        end
    )
    self.app:registerEvent("BrownieHelper_AuctionStateChanged", function(state, itemInfo, bidSetup) self:updateView(state, itemInfo, bidSetup) end)
    self.app:registerEvent("BrownieHelper_BidsChanged", function(bids) self:updateBids(bids) end)
    self.app:registerEvent("BrownieHelper_WinnerChanged",
        function()
            if self.app.winningBid == nil then
                AuctionWizardWinnerLabel:SetText("")
                AuctionWizardWinningBidLabel:SetText("")
                AuctionWizardBidTable:clearSelections()
                AuctionWizardFrameFinalizeButton:Disable()
            else
                AuctionWizardWinnerLabel:SetText(self.app.winningBid.charactername)
                AuctionWizardWinningBidLabel:SetText(tostring(self.app.winningBid.bid))
                self:OnWinnerSelected(self.app.winningBid.charactername)
                if self.app:getMode()>=BROWNIEHELPER_MASTERLOOTER then AuctionWizardFrameFinalizeButton:Enable() end
            end
        end
    )
    
end

--Called by auctionhandler
function AuctionWizardFrame:initializeAuction(itemInfo, bidSetup)

    --Save the important stuff
    self.itemInfo = itemInfo
    self.bidSetup = bidSetup
    
    --Show us if appropriate
    if self.app:getMode()>=BROWNIEHELPER_MASTERLOOTER then self:Show()
    elseif self.app:getMode()>=BROWNIEHELPER_AUDITOR then
        
        if self.app:getDb().Options['ShowAuctionWindow'] then
            self:Show()
        else
            yesnoDialog("The master looter is about to start an auction for:\n"..itemInfo.link..".\n\nWould you like to watch the auction as its happening?\n\nNote: if you're planning on bidding in this auction you should probably answer no.",
                function(response)
                    if response==true then self:Show() end
                end
            )
        end
    end
    
end

--View updates
function AuctionWizardFrame:OnWinnerSelected(characterName)
    
    --If we're not the ml update the view so that the corret row is selected
    for i,row in pairs(AuctionWizardBidTable:getRows()) do
        if row.characterName==characterName then
            row.wiTableSelected = true
        else
            row.wiTableSelected = false
        end
    end
    AuctionWizardBidTable:updateView()
    
end

function AuctionWizardFrame:bidSelected(row, selected)
    --Pass off to manual winner selection
    if self.state==BROWNIEHELPER_POSTAUCTION then
        if selected then self.app:selectWinner(row.characterName)
        else self.app:selectWinner()
        end
    end
    
end

function AuctionWizardFrame:updateBids(bids)
    
    AuctionWizardBidTable:clearRows()
    for playerName,bid in pairs(bids) do
        AuctionWizardBidTable:addRow({
            ["Player"] = playerName,
            ["Character"] = (playerName==bid.charactername and "" or bid.charactername),
            ["Points"] = (bid.playerpoints or getPlayerPoints(bid.charactername, self.bidSetup)),
            ["Bid"] = (bid.bid and tostring(bid.bid) or ""),
            ["Roll"] = (bid.roll and tostring(bid.roll) or ""),
            characterName=bid.charactername,
        })
    end
    --By virtue of assigning all new row objects we clear the current selection.
    
end

function AuctionWizardFrame:updateView(state, itemInfo, bidSetup)

    self.state = state
    self.itemInfo = itemInfo
    self.bidSetup = bidSetup
    
    --Enable or disable buttons based on state
    if self.app:getMode()>=BROWNIEHELPER_MASTERLOOTER then
        AuctionWizardFrameCancelButton:SetText("Cancel auction")
        
        AuctionWizardFrameAddBidButton:Enable()
        AuctionWizardFrameRemoveBidButton:Enable()
        AuctionWizardFrameWhispersButton:Enable()
        
        --Masterlooter mode
        if state==BROWNIEHELPER_PREAUCTION then
            AuctionWizardFrameOpenButton:Enable()
            AuctionWizardFrameCloseBiddingButton:Disable()
            AuctionWizardFrameFindWinnerButton:Disable()
            AuctionWizardFrameFinalizeButton:Disable()
            
            AuctionWizardFrameNextButton:Enable()
            if self.bidSetup.nextPhase then AuctionWizardFrameNextButton:SetText("Next phase")
            elseif self.bidSetup.nextItem then AuctionWizardFrameNextButton:SetText("Next item")
            else
                AuctionWizardFrameNextButton:SetText("Abandon")
                AuctionWizardFrameNextButton:Disable()
            end
            
            AuctionWizardItemLabel:SetText(itemInfo.link)
            AuctionWizardPhaseLabel:SetText(bidSetup.biddingsystem.name)
            AuctionWizardInstructionsLabel:SetText(bidSetup.biddingsystem.instructions)
            AuctionWizardRunLabel:SetText(self.app:getCurrentRun())
            AuctionWizardPointPoolLabel:SetText(self.app:getCurrentPointPool())
            AuctionWizardWinnerLabel:SetText("")
            AuctionWizardWinningBidLabel:SetText("")
            
            --Turn on whisper tracking
            self.whisperTracking = true
            self.whispers = {} --{sender = {messages}}
            
        elseif state==BROWNIEHELPER_AUCTIONRUNNING then
            AuctionWizardFrameOpenButton:Disable()
            AuctionWizardFrameCloseBiddingButton:Enable()
            AuctionWizardFrameFindWinnerButton:Disable()
            AuctionWizardFrameFinalizeButton:Disable()
            
        elseif state==BROWNIEHELPER_POSTAUCTION then
            AuctionWizardFrameOpenButton:Enable()
            AuctionWizardFrameCloseBiddingButton:Disable()
            AuctionWizardFrameFindWinnerButton:Enable()
            AuctionWizardFrameFinalizeButton:Disable()
            
            --Clear the table selections, because now it really means something
            AuctionWizardBidTable:clearSelections()
            
        elseif state==BROWNIEHELPER_AUCTIONFINALIZED then
            
            AuctionWizardFrameFindWinnerButton:Disable()
            AuctionWizardFrameOpenButton:Disable()
            AuctionWizardFrameFinalizeButton:Disable()
            
            --This next bit will change if there's a winner.
            if self.bidSetup.nextItem then AuctionWizardFrameNextButton:SetText("Next item")
            else AuctionWizardFrameNextButton:SetText("Finished")
            end
            
        elseif state==BROWNIEHELPER_NOAUCTION then
            self:Hide()
            
            --Turn off whisper tracking
            self.whisperTracking = false
            
        end
        
    else
        --Auditor mode
        AuctionWizardFrameOpenButton:Disable()
        AuctionWizardFrameAddBidButton:Disable()
        AuctionWizardFrameRemoveBidButton:Disable()
        AuctionWizardFrameCloseBiddingButton:Disable()
        AuctionWizardFrameFindWinnerButton:Disable()
        AuctionWizardFrameFinalizeButton:Disable()
        AuctionWizardFrameNextButton:Disable()
        AuctionWizardFrameWhispersButton:Disable()
        AuctionWizardFrameCancelButton:SetText("Close")
        
        if state==BROWNIEHELPER_PREAUCTION then
            AuctionWizardItemLabel:SetText(itemInfo.link)
            AuctionWizardPhaseLabel:SetText(bidSetup.biddingsystem.name)
            AuctionWizardInstructionsLabel:SetText(bidSetup.biddingsystem.instructions)
            AuctionWizardRunLabel:SetText(self.app:getCurrentRun())
            AuctionWizardPointPoolLabel:SetText(self.app:getCurrentPointPool())
            AuctionWizardWinnerLabel:SetText("")
            AuctionWizardWinningBidLabel:SetText("")
            
        elseif state==BROWNIEHELPER_POSTAUCTION then
            
            --Clear the table selections, because now it really means something
            AuctionWizardBidTable:clearSelections()
            
        elseif state==BROWNIEHELPER_NOAUCTION then
            self:updateBids({})
            self:Hide()
        end
        
    end

end

--Event handlers
function AuctionWizardFrame:OnOpen()
    self.app:openBidding()
end

function AuctionWizardFrame:OnClose()

    local closeAuctionDelay = (tonumber(self.app:getDb().Options['CloseAuctionDelay']) or 5)

    if closeAuctionDelay then
        self.app:sendGroupMessage("Bidding on "..self.bidSetup.itemInfo.link.." will close in "..tostring(closeAuctionDelay).." seconds...")
        AuctionWizardFrameCloseBiddingButton:Disable()
        AuctionWizardFrameCloseBiddingButton:SetText("Closing...")
        self.app:ScheduleEvent(
            function()
                if self.state==BROWNIEHELPER_AUCTIONRUNNING then
                    self.app:closeBidding()
                    AuctionWizardFrameCloseBiddingButton:SetText("Close bidding")
                end
            end,
            closeAuctionDelay
        )
    else
        self.app:closeBidding()
    end
    
end

function AuctionWizardFrame:OnCancel()
    if self.app:getMode()>=BROWNIEHELPER_MASTERLOOTER then
        if (self.app.auctionState==BROWNIEHELPER_AUCTIONRUNNING or self.app.auctionState==BROWNIEHELPER_POSTAUCTION) and self.app:hasBids() then
            yesnoDialog("Are you sure you want to cancel this auction?\n\nAll unfinalized information be discarded.",
                function(response)
                    if response==true then self:doCancel() end
                end
            )
        else self:doCancel()
        end
    else
        self:Hide()
    end
end

function AuctionWizardFrame:doCancel()
    if self.state == BROWNIEHELPER_AUCTIONRUNNING then self.app:closeBidding() end
    self.app:clearBidding()
end

function AuctionWizardFrame:OnAddBid()
    AddBidFrame:OnBiddingOpened(self.app:getPlayerBidSetup(UnitName("player")))
    AddBidFrame:Show()
end

function AuctionWizardFrame:OnRemoveBid()
    local selection = AuctionWizardBidTable:getSelections()[1]
    if selection then
        yesnoDialog("Are you sure you want to remove the bid from "..selection.Player.."?",
            function(response)
                if response==true then self.app:removeBid(selection.characterName) end
            end
        )
    end
end

function AuctionWizardFrame:OnFindWinner()
    self.app:findWinner()
end

function AuctionWizardFrame:OnFinalize()
    
    --Ask them if they're sure
    yesnoDialog("Are you sure you want to finalize this auction?\n\nThis will:\nAnnounce the results\nAdjust the winner's points\nAssign the item\n",
        function(response)
            if response==true then self.app:finalizeResults() end
        end
    )
    
end

function AuctionWizardFrame:OnNext()

    if (self.app.auctionState==BROWNIEHELPER_AUCTIONRUNNING or self.app.auctionState==BROWNIEHELPER_POSTAUCTION) and self.app:hasBids() then
        yesnoDialog("Are you sure you want to cancel this auction?\n\nAll unfinalized information be discarded.",
            function(response)
                if response==true then self:doNext() end
            end
        )
    
    else self:doNext()
    
    end

end

function AuctionWizardFrame:doNext()

    --Trigger a clear of the bidding, which will hide us
    self.app:clearBidding()
    --If there's another phase, call setupAuction with the current item, it will handle incrementing the phase
    if self.bidSetup.nextPhase then self.app:startAuction(self.itemInfo)
    
    --If there's another item, open back up the items frame
    elseif self.bidSetup.nextItem then ViewItemsFrame:Show()
    end

end

function AuctionWizardFrame:recieveWhisper(author, message)
    
    --IF we're tracking whispers
    if self.whisperTracking then
        if self.whispers[author] == nil then
            self.whispers[author] = {}
        end
        
        --Do some game time formatting
        local hour,minute = GetGameTime()
        if hour<10 then hour = "0"..tostring(hour)
        else hour = tostring(hour) end
        if minute<10 then minute = "0"..minute
        else minute = tostring(minute) end
        
        table.insert(self.whispers[author], "["..hour..":"..minute.."] "..message)
        
    end

end

function AuctionWizardFrame:rowEnter(row)

    local characterName = (row.Character~="" and row.Character or row.Player)
    
    if self.itemInfo.link then
        
        --Setup auction item tool tip 1
        GameTooltip_SetDefaultAnchor( AuctionWizardItemTooltip1, AuctionWizardFrame )
        AuctionWizardItemTooltip1:ClearAllPoints()
        AuctionWizardItemTooltip1:SetPoint("TOPLEFT", AuctionWizardFrame, "TOPRIGHT", 0, -15)
        AuctionWizardItemTooltip1:SetHyperlink(self.itemInfo.link)
        AuctionWizardItemTooltip1:Show()
        
        --Set the inspection tool tip 1
        local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture = GetItemInfo(self.itemInfo.link) 
        if itemEquipLoc~=nil then
            
            local slotIds = inventorySlotTranslations[itemEquipLoc]
            if slotIds then
                
                for i,slotId in ipairs(slotIds) do
                    local link = GetInventoryItemLink(characterName, slotId)
                    if link then
                        local tooltip = getglobal("AuctionWizardInspectTooltip"..tostring(i))
                        GameTooltip_SetDefaultAnchor( tooltip, AuctionWizardFrame )
                        tooltip:ClearAllPoints()
                        
                        if i==1 then
                            tooltip:SetPoint("TOPLEFT", AuctionWizardItemTooltip1, "TOPRIGHT", 0, 0)
                        else
                            tooltip:SetPoint("TOPLEFT", getglobal("AuctionWizardInspectTooltip"..tostring(i-1)), "BOTTOMLEFT", 0, 0)
                        end 
                        
                        tooltip:SetHyperlink(link)
                        tooltip:Show()
                    end
                end
                
            end
            
        end
        
    end
    
end

function AuctionWizardFrame:rowLeave(row)
    AuctionWizardItemTooltip1:Hide()
    AuctionWizardItemTooltip2:Hide()
    AuctionWizardItemTooltip3:Hide()
    AuctionWizardInspectTooltip1:Hide()
    AuctionWizardInspectTooltip2:Hide()
    AuctionWizardInspectTooltip3:Hide()
    AuctionWizardInspectTooltip4:Hide()
end

function AuctionWizardFrame:OnWhispers()

    if not GameTooltip:IsShown() then
        --position the game tool tip
        GameTooltip_SetDefaultAnchor( GameTooltip, AuctionWizardFrame )
        GameTooltip:ClearAllPoints()
        GameTooltip:SetPoint("TOPLEFT", AuctionWizardFrame, "TOPRIGHT", 0, -15)
        
        --fill in the defined keys
        GameTooltip:AddLine("Whispers from players durring this auction:", HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
        
        for name,whispers in pairs(self.whispers) do
            GameTooltip:AddLine("\nWhispers from "..name.." :", HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
            for i,msg in pairs(whispers) do
                GameTooltip:AddLine(tostring(msg), NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
            end
        end
        
        GameTooltip:Show()
    else
        GameTooltip:Hide()
    end

end

function AuctionWizardFrame:hasBidFrom(characterName)
    for i, row in pairs(AuctionWizardBidTable:getRows()) do
        if characterName == row.Player or characterName == row.Character then return true end
    end
    return false
end

function AuctionWizardFrame:OnItemEnter()

    --position & feed the game tool tip
    if self.itemInfo.link then
        GameTooltip_SetDefaultAnchor( GameTooltip, AuctionWizardFrame )
        GameTooltip:ClearAllPoints()
        GameTooltip:SetPoint("TOPLEFT", AuctionWizardFrame, "TOPRIGHT", 0, -15)
        GameTooltip:SetHyperlink(self.itemInfo.link)
        GameTooltip:AddLine("\n(Click to show a permenant tooltip for this item)", NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true)
        GameTooltip:Show()
    end
    
end

function AuctionWizardFrame:OnItemLeave()
    GameTooltip:Hide()
end

function AuctionWizardFrame:OnItemClick()

    if self.itemInfo.link then
        
        ShowUIPanel(ItemRefTooltip);
        if ( not ItemRefTooltip:IsShown() ) then
            ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE");
        end
        ItemRefTooltip:SetHyperlink(self.itemInfo.link);
        ItemRefTooltip:Show()
        
    end

end

function AuctionWizardFrame:inspectPlayer(row)

    --Try to open the inspect box for the player associated with the double clicked row
    local unitName = (row.Character~="" and row.Character or row.Player)
    InspectUnit(unitName)
    
end
